package util;

import java.util.List;
import java.util.concurrent.*;
import java.util.stream.Collectors;

public class ThreadUtil {

    public static void join(Thread thread) {
        try {
            thread.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void sleepMillis(int millis) { // 毫秒
        try {
            Thread.sleep(millis); // 避免 CPU 高速运转（轮询的弊端），CPU 纳秒级别
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void sleepSeconds(int seconds) { // 秒
        try {
            TimeUnit.SECONDS.sleep(seconds);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    /**
     * 可以把多个 futures 序列化起来，最终返回一个装载有结果的 CompletableFuture 即可，调用 join 方法就够了
     * 当然只能是同一类型（返回的结果）
     */
    public static <T> CompletableFuture<List<T>> sequence(List<CompletableFuture<T>> futures) {
        // 通过 allOf 方法把所有的 futures 放到一起，返回 Void
        CompletableFuture<Void> allDoneFuture = CompletableFuture.allOf(futures.toArray(new CompletableFuture[futures.size()]));
        // 遍历把每一个 futures 通过 join 方法把结果拿到，最终给返回出去 并且是用 CompletableFuture 包装着的
        return allDoneFuture.thenApply(v -> futures.stream().map(CompletableFuture::join).collect(Collectors.<T>toList()));
    }

    /**
     * Java Future 转 CompletableFuture
     */
    public static <T> CompletableFuture<T> toCompletable(Future<T> future, Executor executor) {
        return CompletableFuture.supplyAsync(() -> {
            try {
                return future.get();
            } catch (InterruptedException | ExecutionException e) {
                throw new RuntimeException(e);
            }
        }, executor);
    }
}
